package com.hc.conferencecheck.service.impl;

import com.hc.conferencecheck.entity.QrCode;
import com.hc.conferencecheck.entity.QrCodeExample;
import com.hc.conferencecheck.entity.ResultMsg;
import com.hc.conferencecheck.entity.ResultStatusCode;
import com.hc.conferencecheck.mapper.QrCodeMapper;
import com.hc.conferencecheck.service.ImageService;
import com.hc.conferencecheck.service.QrCodeService;
import com.hc.conferencecheck.utils.UUIDUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.sql.*;

/**
 * 图片处理service实现类
 */
@Transactional
@Service
public class ImageServiceImpl implements ImageService {
    private static final Logger logger = LoggerFactory.getLogger(ImageServiceImpl.class);
    @Resource
    Environment environment;
    @Resource
    private QrCodeMapper qrCodeMapper;
    @Resource
    private QrCodeService qrCodeServiceImpl;

    /**
     * 更新服务器上的某张图片
     */
    public ResultMsg updateImageFormServer(MultipartFile file, int type, int identifyId) {
        //首先删除原图片
        ResultMsg deleteResultMsg = deleteImageFormServer(type, identifyId);
        if (deleteResultMsg.getCode() == 200) {
            //然后保存新图片
            ResultMsg uploadResultMsg = uploadImageToServer(file, type, identifyId);
            if (uploadResultMsg.getCode() == 200) {
                return new ResultMsg(ResultStatusCode.OK.getCode(), ResultStatusCode.OK.getMsg(), "更新图片成功");
            } else {
                return new ResultMsg(ResultStatusCode.EORROR.getCode(), ResultStatusCode.EORROR.getMsg(), "更新图片失败");
            }
        } else {
            return new ResultMsg(ResultStatusCode.EORROR.getCode(), ResultStatusCode.EORROR.getMsg(), "更新图片失败");
        }
    }

    /**
     * 删除服务器上的某张图片
     */
    public ResultMsg deleteImageFormServer(int type, int identifyId) {
        //首先根据条件查询qrcode对象，获取图片保存地址
        //查询获取图片地址
        QrCode qrCode = qrCodeServiceImpl.selectQrCodeByTypeAndIdentifierId(type, identifyId);
        if (qrCode == null) {
            return new ResultMsg(ResultStatusCode.EORROR.getCode(), ResultStatusCode.EORROR.getMsg(), "找不到指定图片");
        }
        // 本地文件路径
        String filePath = qrCode.getImagePath();
        //使用File对象，删除图片；
        File file = new File(filePath);
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                //同时需要删除数据库中保存的图片的地址
                int i = qrCodeServiceImpl.deleteQrCodeByTypeAndIdentifierId(type, identifyId);
                if (i == 1) {
                    return new ResultMsg(ResultStatusCode.OK.getCode(), ResultStatusCode.OK.getMsg(), "删除成功");
                } else {
                    return new ResultMsg(ResultStatusCode.EORROR.getCode(), ResultStatusCode.EORROR.getMsg(), "删除数据库数据失败");
                }
            } else {
                return new ResultMsg(ResultStatusCode.EORROR.getCode(), ResultStatusCode.EORROR.getMsg(), "删除失败");
            }
        } else {
            return new ResultMsg(ResultStatusCode.EORROR.getCode(), ResultStatusCode.EORROR.getMsg(), "文件不存在");
        }
    }

    /**
     * 读取显示服务器上的图片
     */
    public void showIamge(HttpServletResponse response, int type, int identifyId) {
        //查询获取图片地址
        QrCode qrCode = qrCodeServiceImpl.selectQrCodeByTypeAndIdentifierId(type, identifyId);
        if (qrCode == null) {
            return;
        }
        try {
            // 本地文件路径
            String filePath = qrCode.getImagePath();
            File file = new File(filePath);
            // 获取输出流
            OutputStream outputStream = response.getOutputStream();
            FileInputStream fileInputStream = new FileInputStream(file);
            // 读数据
            int count = 0;
            while (count == 0) {
                count = fileInputStream.available();
            }
            byte[] data = new byte[count];
            fileInputStream.read(data);
            fileInputStream.close();
            // 回写
            response.setContentType("image/jpeg");  //设置图片格式
            outputStream.write(data);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 保存图片到服务器
     */
    public ResultMsg uploadImageToServer(MultipartFile file, int type, int identifyId) {
        if (file.isEmpty()) {
            return new ResultMsg(ResultStatusCode.EORROR.getCode(), ResultStatusCode.EORROR.getMsg(), "图片文件不可为空");
        }
        // 获取文件的后缀名
        //获取文件名
        String originalFilename = file.getOriginalFilename();
        String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));

        // 使用UUID+文件后缀作为图片的新名称，防止文件名重复
        String fileName = UUIDUtils.getUUID() + suffixName;
        try {
            String savePath = environment.getProperty("save_path");

            // 检测是否存在目录,如果不存在则创建一个
            File dest = new File(savePath + fileName);
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }

            //保存文件
            File saveFile = new File(savePath + fileName);
            file.transferTo(saveFile);

            logger.info("上传成功后的文件路径未：" + savePath + fileName);
            //保存图片路径
            QrCode qrCode = new QrCode();
            qrCode.setType(type);
            qrCode.setIdentifyId(identifyId);
            qrCode.setImagePath(savePath + fileName);
            //首先进行查询，如果该会议已经存储了图片，那么首先删除该图片，再插入指定的图片
            int i = qrCodeMapper.insert(qrCode);
            if (i == 1) {
                return new ResultMsg(ResultStatusCode.OK.getCode(), ResultStatusCode.OK.getMsg(), "图片上传成功");
            } else {
                return new ResultMsg(ResultStatusCode.EORROR.getCode(), ResultStatusCode.EORROR.getMsg(), "图片上传失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 显示某张图片
     */
    public void showImage(int type, int identifyId, HttpServletResponse response) {
        Connection connection = null;
        PreparedStatement ptmt = null;
        ResultSet rs = null;
        try {
            connection = getConnection();
            String sql = "select * from image where type =? AND  identify_id = ? ";
            ptmt = connection.prepareStatement(sql);
            ptmt.setInt(1, type);
            ptmt.setInt(2, identifyId);
            rs = ptmt.executeQuery();
            while (rs.next()) {
                //解析结果集,将图片对象转换为字节数组
                byte[] images = rs.getBytes("image_file");
                response.setContentType("image/jpeg");  //设置图片格式
                OutputStream out = response.getOutputStream(); //打开输出流

                out.write(images);  //输出图片
                out.flush();    //输出
                out.close();  //关闭输出
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            close(rs, ptmt, connection);
        }
    }

    /**
     * 更新某张图片
     */
    public ResultMsg updateImage(MultipartFile file, int type, int identifyId) {
        if (file.isEmpty()) {
            return new ResultMsg(ResultStatusCode.EORROR.getCode(), ResultStatusCode.EORROR.getMsg(), "图片更新失败");
        }

        Connection connection = null;
        PreparedStatement ptmt = null;
        try {
            connection = getConnection();
            //开始上传图片
            InputStream inputStream = file.getInputStream();
            //sql语句
            String sql = "update image set image_file = ? where 1=1 and type = ? and identify_id = ?";
            ptmt = connection.prepareStatement(sql);
            //设置参数
            ptmt.setBinaryStream(1, inputStream, inputStream.available());
            ptmt.setInt(2, type);
            ptmt.setInt(3, identifyId);
            int i = ptmt.executeUpdate();
            //关闭流对象
            inputStream.close();
            if (i == 1) {
                return new ResultMsg(ResultStatusCode.OK.getCode(), ResultStatusCode.OK.getMsg(), "图片更新成功");
            } else {
                return new ResultMsg(ResultStatusCode.EORROR.getCode(), ResultStatusCode.EORROR.getMsg(), "图片更新失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭数据库资源
            close(null, ptmt, connection);
        }
        return null;
    }

    /**
     * 上传图片到数据库
     */
    public ResultMsg uploadImage(MultipartFile file, int type, int identifyId) {
        if (file.isEmpty()) {
            return new ResultMsg(ResultStatusCode.EORROR.getCode(), ResultStatusCode.EORROR.getMsg(), "图片上传失败");
        }

        Connection connection = null;
        PreparedStatement ptmt = null;
        try {
            connection = getConnection();
            //开始上传图片
            InputStream inputStream = file.getInputStream();
            //sql语句
            String sql = "insert into image (type,identify_id,image_file) values(?,?,?)";
            ptmt = connection.prepareStatement(sql);
            //设置参数
            ptmt.setInt(1, type);
            ptmt.setInt(2, identifyId);
            ptmt.setBinaryStream(3, inputStream, inputStream.available());
            int i = ptmt.executeUpdate();
            //关闭流对象
            inputStream.close();
            if (i == 1) {
                return new ResultMsg(ResultStatusCode.OK.getCode(), ResultStatusCode.OK.getMsg(), "图片上传成功");
            } else {
                return new ResultMsg(ResultStatusCode.EORROR.getCode(), ResultStatusCode.EORROR.getMsg(), "图片上传失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭数据库资源
            close(null, ptmt, connection);
        }
        return null;
    }

    /**
     * 传统jdbc编程:获取数据库连接
     */
    public Connection getConnection() {
        //从配置文件中获取获取数据库连接信息
        String driver = environment.getProperty("spring.datasource.driver-class-name");
        String url = environment.getProperty("spring.datasource.url");
        String user = environment.getProperty("spring.datasource.username");
        String password = environment.getProperty("spring.datasource.password");

        Connection connection = null;
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url, user, password);
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
            return null;
        }
        return connection;
    }

    /**
     * 关闭资源
     *
     * @param resultSet
     * @param statement
     * @param connection
     */
    private void close(ResultSet resultSet, Statement statement, Connection connection) {
        //倒序关闭资源
        try {
            if (resultSet != null && !resultSet.isClosed()) {
                resultSet.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        try {
            if (statement != null && !statement.isClosed()) {
                statement.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        try {
            if (connection != null && !connection.isClosed()) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


}
